<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>13.2. Zend_Dom_Query</title>
<link rel="stylesheet" href="dbstyle.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.72.0">
<link rel="start" href="index.html" title="Programmer's Reference Guide">
<link rel="up" href="zend.dom.html" title="Chapter 13. Zend_Dom">
<link rel="prev" href="zend.dom.html" title="Chapter 13. Zend_Dom">
<link rel="next" href="zend.exception.html" title="Chapter 14. Zend_Exception">
<link rel="chapter" href="introduction.html" title="Chapter 1. Introduction to Zend Framework">
<link rel="chapter" href="zend.acl.html" title="Chapter 2. Zend_Acl">
<link rel="chapter" href="zend.auth.html" title="Chapter 3. Zend_Auth">
<link rel="chapter" href="zend.cache.html" title="Chapter 4. Zend_Cache">
<link rel="chapter" href="zend.config.html" title="Chapter 5. Zend_Config">
<link rel="chapter" href="zend.console.getopt.html" title="Chapter 6. Zend_Console_Getopt">
<link rel="chapter" href="zend.controller.html" title="Chapter 7. Zend_Controller">
<link rel="chapter" href="zend.currency.html" title="Chapter 8. Zend_Currency">
<link rel="chapter" href="zend.date.html" title="Chapter 9. Zend_Date">
<link rel="chapter" href="zend.db.html" title="Chapter 10. Zend_Db">
<link rel="chapter" href="zend.debug.html" title="Chapter 11. Zend_Debug">
<link rel="chapter" href="zend.dojo.html" title="Chapter 12. Zend_Dojo">
<link rel="chapter" href="zend.dom.html" title="Chapter 13. Zend_Dom">
<link rel="chapter" href="zend.exception.html" title="Chapter 14. Zend_Exception">
<link rel="chapter" href="zend.feed.html" title="Chapter 15. Zend_Feed">
<link rel="chapter" href="zend.filter.html" title="Chapter 16. Zend_Filter">
<link rel="chapter" href="zend.form.html" title="Chapter 17. Zend_Form">
<link rel="chapter" href="zend.gdata.html" title="Chapter 18. Zend_Gdata">
<link rel="chapter" href="zend.http.html" title="Chapter 19. Zend_Http">
<link rel="chapter" href="zend.infocard.html" title="Chapter 20. Zend_InfoCard">
<link rel="chapter" href="zend.json.html" title="Chapter 21. Zend_Json">
<link rel="chapter" href="zend.layout.html" title="Chapter 22. Zend_Layout">
<link rel="chapter" href="zend.ldap.html" title="Chapter 23. Zend_Ldap">
<link rel="chapter" href="zend.loader.html" title="Chapter 24. Zend_Loader">
<link rel="chapter" href="zend.locale.html" title="Chapter 25. Zend_Locale">
<link rel="chapter" href="zend.log.html" title="Chapter 26. Zend_Log">
<link rel="chapter" href="zend.mail.html" title="Chapter 27. Zend_Mail">
<link rel="chapter" href="zend.measure.html" title="Chapter 28. Zend_Measure">
<link rel="chapter" href="zend.memory.html" title="Chapter 29. Zend_Memory">
<link rel="chapter" href="zend.mime.html" title="Chapter 30. Zend_Mime">
<link rel="chapter" href="zend.openid.html" title="Chapter 31. Zend_OpenId">
<link rel="chapter" href="zend.paginator.html" title="Chapter 32. Zend_Paginator">
<link rel="chapter" href="zend.pdf.html" title="Chapter 33. Zend_Pdf">
<link rel="chapter" href="zend.registry.html" title="Chapter 34. Zend_Registry">
<link rel="chapter" href="zend.rest.html" title="Chapter 35. Zend_Rest">
<link rel="chapter" href="zend.search.lucene.html" title="Chapter 36. Zend_Search_Lucene">
<link rel="chapter" href="zend.server.html" title="Chapter 37. Zend_Server">
<link rel="chapter" href="zend.service.html" title="Chapter 38. Zend_Service">
<link rel="chapter" href="zend.session.html" title="Chapter 39. Zend_Session">
<link rel="chapter" href="zend.soap.html" title="Chapter 40. Zend_Soap">
<link rel="chapter" href="zend.test.html" title="Chapter 41. Zend_Test">
<link rel="chapter" href="zend.text.html" title="Chapter 42. Zend_Text">
<link rel="chapter" href="zend.timesync.html" title="Chapter 43. Zend_TimeSync">
<link rel="chapter" href="zend.translate.html" title="Chapter 44. Zend_Translate">
<link rel="chapter" href="zend.uri.html" title="Chapter 45. Zend_Uri">
<link rel="chapter" href="zend.validate.html" title="Chapter 46. Zend_Validate">
<link rel="chapter" href="zend.version.html" title="Chapter 47. Zend_Version">
<link rel="chapter" href="zend.view.html" title="Chapter 48. Zend_View">
<link rel="chapter" href="zend.xmlrpc.html" title="Chapter 49. Zend_XmlRpc">
<link rel="appendix" href="requirements.html" title="Appendix A. Zend Framework Requirements">
<link rel="appendix" href="coding-standard.html" title="Appendix B. Zend Framework Coding Standard for PHP">
<link rel="appendix" href="copyrights.html" title="Appendix C. Copyright Information">
<link rel="index" href="the.index.html" title="Index">
<link rel="subsection" href="zend.dom.query.html#zend.dom.query.operation" title="13.2.1. Theory of Operation">
<link rel="subsection" href="zend.dom.query.html#zend.dom.query.methods" title="13.2.2. Methods Available">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader"><table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">13.2. Zend_Dom_Query</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="zend.dom.html">Prev</a> </td>
<th width="60%" align="center">Chapter 13. Zend_Dom</th>
<td width="20%" align="right"> <a accesskey="n" href="zend.exception.html">Next</a>
</td>
</tr>
</table></div>
<div class="sect1" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="zend.dom.query"></a>13.2. Zend_Dom_Query</h2></div></div></div>
<p>
        <code class="code">Zend_Dom_Query</code> provides mechanisms for querying XML and
        (X)HTML documents utilizing either XPath or CSS selectors. It was
        developed to aid with functional testing of MVC applications, but could
        also be used for rapid development of screen scrapers.
    </p>
<p>
        CSS selector notation is provided as a simpler and more familiar
        notation for web developers to utilize when querying documents with XML
        structures. The notation should be familiar to anybody who has developed
        Cascading Style Sheets or who utilizes Javascript toolkits that provide
        functionality for selecting nodes utilizing CSS selectors 
        (<a href="http://prototypejs.org/api/utility/dollar-dollar" target="_top">Prototype's
            $$()</a> and 
        <a href="http://api.dojotoolkit.org/jsdoc/dojo/HEAD/dojo.query" target="_top">Dojo's 
            dojo.query</a> were both inspirations for the component).
    </p>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.dom.query.operation"></a>13.2.1. Theory of Operation</h3></div></div></div>
<p>
            To use <code class="code">Zend_Dom_Query</code>, you instantiate a
            <code class="code">Zend_Dom_Query</code> object, optionally passing a document to
            query (a string). Once you have a document, you can use either the
            <code class="code">query()</code> or <code class="code">queryXpath()</code> methods; each
            method will return a <code class="code">Zend_Dom_Query_Result</code> object with
            any matching nodes.
        </p>
<p>
            The primary difference between <code class="code">Zend_Dom_Query</code> and using
            DOMDocument + DOMXPath is the ability to select against CSS
            selectors. You can utilize any of the following, in any combination:
        </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                <span class="emphasis"><em>element types</em></span>: provide an element type to
                match: 'div', 'a', 'span', 'h2', etc.
            </p></li>
<li><p>
                <span class="emphasis"><em>style attributes</em></span>: CSS style attributes to
                match: '.error', 'div.error', 'label.required', etc. If an
                element defines more than one style, this will match as long as
                the named style is present anywhere in the style declaration.
            </p></li>
<li><p>
                <span class="emphasis"><em>id attributes</em></span>: element ID attributes to
                match: '#content', 'div#nav', etc.
            </p></li>
<li>
<p>
                    <span class="emphasis"><em>arbitrary attributes</em></span>: arbitrary element
                    attributes to match. Three different types of matching are
                    provided:
                </p>
<div class="itemizedlist"><ul type="circle">
<li><p>
                        <span class="emphasis"><em>exact match</em></span>: the attribute exactly
                        matches the string: 'div[bar="baz"]' would match a div
                        element with a "bar" attribute that exactly matches the
                        value "baz".
                    </p></li>
<li><p>
                        <span class="emphasis"><em>word match</em></span>: the attribute contains
                        a word matching the string: 'div[bar~="baz"]' would match a div
                        element with a "bar" attribute that contains the
                        word "baz". '&lt;div bar="foo baz"&gt;' would match, but '&lt;div
                                bar="foo bazbat"&gt;' would not.
                    </p></li>
<li><p>
                        <span class="emphasis"><em>substring match</em></span>: the attribute contains
                        the string: 'div[bar*="baz"]' would match a div
                        element with a "bar" attribute that contains the
                        string "baz" anywhere within it.
                    </p></li>
</ul></div>
<div class="itemizedlist">
<p>
                    <span class="emphasis"><em>direct descendents</em></span>: utilize '&gt;' between
                    selectors to denote direct descendents. 'div &gt; span' would
                    select only 'span' elements that are direct descendents of a
                    'div'. Can also be used with any of the selectors above.
                </p>
<ul type="circle"></ul>
</div>
<div class="itemizedlist">
<p>
                        <span class="emphasis"><em>descendents</em></span>: string together
                        multiple selectors to indicate a hierarchy along which
                        to search.  'div .foo span #one' would select an element
                        of id 'one' that is a descendent of arbitrary depth
                        beneath a 'span' element, which is in turn a descendent
                        of arbitrary depth beneath an element with a class of
                        'foo', that is an descendent of arbitrary depth beneath
                        a 'div' element. For example, it would match the link to
                        the word 'One' in the listing below:
                    </p>
<pre class="programlisting">
&lt;div&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;td class="foo"&gt;
                &lt;div&gt;
                    Lorem ipsum &lt;span class="bar"&gt;
                        &lt;a href="/foo/bar" id="one"&gt;One&lt;/a&gt; 
                        &lt;a href="/foo/baz" id="two"&gt;Two&lt;/a&gt; 
                        &lt;a href="/foo/bat" id="three"&gt;Three&lt;/a&gt; 
                        &lt;a href="/foo/bla" id="four"&gt;Four&lt;/a&gt; 
                    &lt;/span&gt;
                &lt;/div&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;/div&gt;
</pre>
<ul type="circle"></ul>
</div>
</li>
</ul></div>
<p>
            Once you've performed your query, you can then work with the result
            object to determine information about the nodes, as well as to pull
            them and/or their content directly for examination and manipulation.
            <code class="code">Zend_Dom_Query_Result</code> implements <code class="code">Countable</code>
            and <code class="code">Iterator</code>, and store the results internally as
            DOMNodes/DOMElements.  As an example, consider the following call,
            that selects against the HTML above:
        </p>
<pre class="programlisting">
$dom = new Zend_Dom_Query($html);
$results = $dom-&gt;query('.foo .bar a');

$count = count($results); // get number of matches: 4
foreach ($results as $result) {
    // $result is a DOMElement
}
</pre>
<p>
            <code class="code">Zend_Dom_Query</code> also allows straight XPath queries
            utilizing the <code class="code">queryXpath()</code> method; you can pass any
            valid XPath query to this method, and it will return a
            <code class="code">Zend_Dom_Query_Result</code> object.
        </p>
</div>
<div class="sect2" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="zend.dom.query.methods"></a>13.2.2. Methods Available</h3></div></div></div>
<p>
            The <code class="code">Zend_Dom_Query</code> family of classes have the following
            methods available.
        </p>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.dom.query.methods.zenddomquery"></a>13.2.2.1. Zend_Dom_Query</h4></div></div></div>
<p>
                The following methods are available to
                <code class="code">Zend_Dom_Query</code>:
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                    <code class="code">setDocumentXml($document)</code>: specify an XML
                    string to query against.
                </p></li>
<li><p>
                    <code class="code">setDocumentXhtml($document)</code>: specify an XHTML
                    string to query against.
                </p></li>
<li><p>
                    <code class="code">setDocumentHtml($document)</code>: specify an HTML
                    string to query against.
                </p></li>
<li><p>
                    <code class="code">setDocument($document)</code>: specify a
                    string to query against; <code class="code">Zend_Dom_Query</code> will
                    then attempt to autodetect the document type.
                </p></li>
<li><p>
                    <code class="code">getDocument()</code>: retrieve the original document
                    string provided to the object.
                </p></li>
<li><p>
                    <code class="code">getDocumentType()</code>: retrieve the document
                    type of the document provided to the object; will be one of
                    the <code class="code">DOC_XML</code>, <code class="code">DOC_XHTML</code>, or
                    <code class="code">DOC_HTML</code> class constants.
                </p></li>
<li><p>
                    <code class="code">query($query)</code>: query the document using CSS
                    selector notation.
                </p></li>
<li><p>
                    <code class="code">queryXpath($xPathQuery)</code>: query the document
                    using XPath notation.
                </p></li>
</ul></div>
</div>
<div class="sect3" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="zend.dom.query.methods.zenddomqueryresult"></a>13.2.2.2. Zend_Dom_Query_Result</h4></div></div></div>
<p>
                As mentioned previously, <code class="code">Zend_Dom_Query_Result</code>
                implements both <code class="code">Iterator</code> and
                <code class="code">Countable</code>, and as such can be used in a
                <code class="code">foreach</code> loop as well as with the
                <code class="code">count()</code> function. Additionally, it exposes the
                following methods:
            </p>
<div class="itemizedlist"><ul type="disc">
<li><p>
                    <code class="code">getCssQuery()</code>: return the CSS selector query
                    used to produce the result (if any).
                </p></li>
<li><p>
                    <code class="code">getXpathQuery()</code>: return the XPath query
                    used to produce the result. Internally,
                    <code class="code">Zend_Dom_Query</code> converts CSS selector queries to
                    XPath, so this value will always be populated.
                </p></li>
<li><p>
                    <code class="code">getDocument()</code>: retrieve the DOMDocument the
                    selection was made against.
                </p></li>
</ul></div>
</div>
</div>
</div>
<div class="navfooter"><table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="zend.dom.html">Prev</a> </td>
<td width="20%" align="center"><a accesskey="u" href="zend.dom.html">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="zend.exception.html">Next</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 13. Zend_Dom </td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top"> Chapter 14. Zend_Exception</td>
</tr>
</table></div>
<div class="revinfo"></div>
</body>
</html>
